<?php
namespace app\admin\model;
use think\Model;
use app\admin\controller\Auth;

/**
 * 权限菜单管理
 */
class Menu extends Model
{
	/**
	 * 库名和表名一起配置(方便之后分库处理)
	 */
	protected $table = 'menu';
	
	private $formatTree; //用于树型数组完成递归格式的全局变量
	
	/**
	 * 菜单列表
	 */
	public function lists($page = 15,$map = []){
		$list = \think\Db::table($this->table)->where($map)->paginate($page);
		return $list;
	}
	
	/**
	 * 将menu菜单以tree的形式展示出来
	 */
	public function getMenuTree(){
		$list = \think\Db::table($this->table)->where(['status'=>1])->select();
		return $list;
	}
	
	/**
	 * 通过id获取一条菜单信息
	 * @param int $id 菜单id
	 */
	public function getFindOne($id){
		return \think\Db::table($this->table)->where(['id'=>$id])->find();
	}
	
	/**
	 * 添加菜单
	 */
	public function addMenu($data){
		return \think\Db::table($this->table)->insertGetId($data);
	}
	
	/**
	 * 编辑菜单
	 */
	public function editMenu($input){
		return \think\Db::table($this->table)->update($input);
	}
	
	/**
	 * 设置菜单的状态信息
	 */
	public function stateMenu($map,$data){
		return \think\Db::table($this->table)->where($map)->update($data);
	}
	
	/**
	 * 物理删除
	 */
	public function removeMenu($id){
		$return = false;
		$map =$id;
		$m = \think\Db::table($this->table)->field('id,pid')->where(['id'=>['in',$map]])->select();
		//dump($m);exit;
		$count = 0;
		foreach($m as $k=>$v){
			$count += \think\Db::table($this->table)->field('id')->where(['pid'=>$v['id']])->count();
		}
		if($count == 0){
			$return =  \think\Db::table($this->table)->delete($map);
		}
		return $return;
	}
	
	/**
	 * 将格式数组转换为树
	 *
	 * @param array $list
	 * @param integer $level 进行递归时传递用的参数
	 */
	private function _toFormatTree($list,$level=0,$title = 'title') {
		foreach($list as $key=>$val){
			$tmp_str='┃'.str_repeat("--┣",$level);
			$tmp_str.="";

			$val['level'] = $level;
			$val['title_show'] =$level==0?'┣'.$val[$title]."--":$tmp_str.$val[$title]."";
			if(!array_key_exists('_child',$val)){
				array_push($this->formatTree,$val);
			}else{
				$tmp_ary = $val['_child'];
				unset($val['_child']);
				array_push($this->formatTree,$val);
				$this->_toFormatTree($tmp_ary,$level+1,$title); //进行下一层递归
			}
		}
		return;
	}

	public function toFormatTree($list,$title = 'title',$pk='id',$pid = 'pid',$root = 0){
		$list = list_to_tree($list,$pk,$pid,'_child',$root);
		$this->formatTree = array();
		$this->_toFormatTree($list,0,$title);
		return $this->formatTree;
	}
	
	/**
	 * 获取菜单节点
	 */
	public function returnNodes($tree = true){
        static $tree_nodes = array();
        if ( $tree && !empty($tree_nodes[(int)$tree]) ) {
            return $tree_nodes[$tree];
        }
        if((int)$tree){
            $where           = [];
            $where['status'] = 1;
            $list = \think\Db::table($this->table)->field('id,pid,title,url')
                ->where( $where )->order('sort asc')->select();
            foreach ($list as $key => $value) {
                if( stripos($value['url'],request()->module())!==0 ){
                    $list[$key]['url'] = request()->module().'/'.$value['url'];
                }
            }
            $nodes = list_to_tree($list,$pk='id',$pid='pid',$child='operator',$root=0);
            foreach ($nodes as $key => $value) {
                if(!empty($value['operator'])){
                    $nodes[$key]['child'] = $value['operator'];
                    unset($nodes[$key]['operator']);
                }
            }
        }else{
            $where           = [];
            $where['status'] = 1;
            $nodes = \think\Db::table($this->table)->field('title,url,tip,pid')
                ->where( $where )->order('sort asc')->select();
            foreach ($nodes as $key => $value) {
                if( stripos($value['url'],request()->module())!==0 ){
                    $nodes[$key]['url'] = request()->module().'/'.$value['url'];
                }
            }
        }
        $tree_nodes[(int)$tree]   = $nodes;
        return $nodes;
    }

    /**
     * 获取顶部一级菜单
     */
    public function getTopMenus()
    {
        $auth_menu = session('admin.auth_top_menu');
        if( $auth_menu ) {
            return $auth_menu;
        }else{
            //获取根菜单
            $root_menu = \think\Db::table( $this->table )->where( ['pid'=>0, 'status'=>1] )
                        ->order('sort asc')->select();
            $root      = [];
            //判断是否添加了根菜单，并且去验证是否具备权限
            if( $root_menu ) {
                foreach( $root_menu as $k=>$v ) {
                    //超级管理员不需要检测菜单权限
                    $user_auth_session = session('admin.user_auth');
                    if( 1 != intval( $user_auth_session['uid'] ) ) {
                        if( $this->checkRule( request()->module().'/'.$v['url'] ) ) {
                            $root[$k] = $v;
                        }
                    } else {
                        $root[$k] = $v;
                    }
                    
                }
            }
            session( 'admin.auth_top_menu',$root );
            return $root;
        }
    }

    /**
     * 获取所有的权限菜单
     */
    public function getAllLeftMenu()
    {
        $result        = array();
        $all_auth_menu = session('admin.all_left_auth_menu');
        if( $all_auth_menu ) {
            return $all_auth_menu;
        } else {
            $topMenu = $this->getTopMenus();
            if( $topMenu ) {
                foreach( $topMenu as $key=>$val ) {
                    $result[$val['id']] = $this->getMenus( $val['id'] );
                }
            }
        }
        session( 'admin.all_left_auth_menu', $result );
        return $result;
    }
	
	/**
     * 获取控制器菜单数组,二级菜单元素位于一级菜单的'_child'元素中
     */
    public function getMenus( $id='' )
    {
        $spm  = $id;
        if( !$spm ) {
            return array();
        }
        //获取根菜单
        $root_menu = \think\Db::table( $this->table )->where( ['pid'=>$spm,'status'=>1] )
                     ->order( 'sort asc' )->select();
        $root      = [];
        //判断是否添加了根菜单，并且去验证是否具备权限
        if( $root_menu ) {
            foreach( $root_menu as $k=>$v ) {
                //超级管理员不需要检测菜单权限
                $user_auth_session = session('admin.user_auth');
                if( 1 != intval( $user_auth_session['uid'] ) ) {
                    if( $this->checkRule( request()->module().'/'.$v['url'] ) ) {
                        $root[$k] = $v;
                    }
                }else{
                    $root[$k] = $v;
                }

            }
            $result = array();
            if( count( $root ) > 0 ) {
                foreach( $root as $key=>$val ) {
                    $result[$val['group']][] = $val;
                }
            }
            $root = $result;
        }
        return $root;
		
    }
	
	/**
     * 权限检测
     * @param string  $url    检测的规则
     * @return boolean
     */
    protected function checkRule( $url )
    {
        $auth              = new Auth();
        $user_auth_session = session( 'admin.user_auth' );
		if( $auth->check( $url, $user_auth_session['uid'] ) ) {
			return true;
		}
		return false;
    }
}
